package com.yanqu.road.server.manger.config;

import com.yanqu.road.entity.clinic.DiseaseData;
import com.yanqu.road.entity.clinic.UserClinicData;
import com.yanqu.road.entity.config.badge.BadgeConfig;
import com.yanqu.road.entity.config.beauty.BeautySkillInfo;
import com.yanqu.road.entity.config.building.BuildingInfo;
import com.yanqu.road.entity.config.building.BuildingStaff;
import com.yanqu.road.entity.config.building.BuildingUpgrade;
import com.yanqu.road.entity.config.clinic.DiseaseInfo;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.config.manor.ManorConfig;
import com.yanqu.road.entity.config.patrons.PatronsInfo;
import com.yanqu.road.entity.config.skill.SkillInfo;
import com.yanqu.road.entity.config.skin.SkinInfo;
import com.yanqu.road.entity.config.winery.WineryConfig;
import com.yanqu.road.entity.cricket.UserCricketData;
import com.yanqu.road.entity.curio.UserCurioData;
import com.yanqu.road.entity.curio.config.CurioBadgeInfo;
import com.yanqu.road.entity.drugstore.UserDrugChuFangData;
import com.yanqu.road.entity.drugstore.UserDrugStoreData;
import com.yanqu.road.entity.drugstore.config.DrugStoreBadgeInfo;
import com.yanqu.road.entity.drugstore.config.DrugStoreDrugUpgradeInfo;
import com.yanqu.road.entity.dto.CrossPatronsSkill;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.kowloon.KowloonBuildingData;
import com.yanqu.road.entity.kowloon.config.KowloonBuildingConfig;
import com.yanqu.road.entity.manor.ManorHarvestData;
import com.yanqu.road.entity.manor.ManorTechnologyData;
import com.yanqu.road.entity.player.*;
import com.yanqu.road.entity.servercenter.ServerInfo;
import com.yanqu.road.entity.union.cross.CrossUnionInfo;
import com.yanqu.road.entity.union.cross.CrossUnionMember;
import com.yanqu.road.entity.winery.UserWineryData;
import com.yanqu.road.entity.winery.UserWineryInfoData;
import com.yanqu.road.entity.wingroom.UserWingRoomData;
import com.yanqu.road.entity.wingroom.config.WingRoomLvConfig;
import com.yanqu.road.logic.bussiness.config.BuildingBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.model.kowloon.KowloonConfig;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.curio.CurioModule;
import com.yanqu.road.server.gameplayer.module.clinic.ClinicModule;
import com.yanqu.road.server.gameplayer.module.cricket.CricketModule;
import com.yanqu.road.server.gameplayer.module.drugstore.DrugStoreModule;
import com.yanqu.road.server.gameplayer.module.kowloon.KowloonModule;
import com.yanqu.road.server.gameplayer.module.manor.ManorHarvestModel;
import com.yanqu.road.server.gameplayer.module.manor.ManorModule;
import com.yanqu.road.server.gameplayer.module.manor.ManorTechnologyModel;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.player.AttributeModule;
import com.yanqu.road.server.gameplayer.module.player.BeautyModule;
import com.yanqu.road.server.gameplayer.module.player.EstateWarModule;
import com.yanqu.road.server.gameplayer.module.player.HouseModule;
import com.yanqu.road.server.gameplayer.module.skin.SkinModule;
import com.yanqu.road.server.gameplayer.module.specialserver.IceServerModule;
import com.yanqu.road.server.gameplayer.module.winery.WineryModule;
import com.yanqu.road.server.gameplayer.module.wingroom.WingRoomModule;
import com.yanqu.road.server.manger.ConfigMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.manger.activity.curio.CurioConfigMgr;
import com.yanqu.road.server.manger.activity.curio.CurioMgr;
import com.yanqu.road.server.manger.drugstore.DrugStoreConfigMgr;
import com.yanqu.road.server.manger.kowloon.KowloonMgr;
import com.yanqu.road.server.manger.manor.FishPondMgr;
import com.yanqu.road.server.manger.manor.ManorMgr;
import com.yanqu.road.server.manger.union.CrossUnionMgr;
import com.yanqu.road.server.manger.wingroom.WingRoomConfigMgr;
import com.yanqu.road.utils.config.Config;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;

public class BuildingMgr extends TempMgr {

	/**
	 * 建筑列表
	 */
	private static Map<Integer, BuildingInfo> buildingInfoMap;
	/**
	 * 招募员工花费表
	 */
	private static Map<Integer, BuildingStaff> buildingStaffMap;
	/**
	 * 建筑升级表
	 */
	private static Map<Integer, Map<Integer,BuildingUpgrade>> buildingUpgradeMap;

	@Override
	public boolean stop() {
		return false;
	}

	@Override
	public boolean save() {
		return false;
	}

	@Override
	public boolean reloadConfig() {
		buildingInfoMap = BuildingBussiness.getBuildingInfoMap();
		if (buildingInfoMap.size() <= 0) {
			return false;
		}

		buildingStaffMap = BuildingBussiness.getBuildingStaffMap();
		if (buildingStaffMap.size() <= 0) {
			return false;
		}

		buildingUpgradeMap = BuildingBussiness.getBuildingUpgradeMap();
		if(buildingUpgradeMap.size() <= 0){
			return false;
		}
		return true;
	}

	@Override
	public boolean reloadData() throws Exception {
		return true;
	}

	@Override
	public boolean init() throws Exception {
		return reload();
	}

	public static BuildingInfo getBuildingInfo(int buildingId) {
		return buildingInfoMap.get(buildingId);
	}
	/**
	 * 获取招募员工的花费
	 */
	public static BigDecimal getAddStaffCost(GamePlayer player, int buildingId, int count) {
		BuildingInfo buildingInfo = getBuildingInfo(buildingId);
		if (buildingStaffMap.containsKey(count + 1)) {
			double skillAddition = player.getModule(BeautyModule.class).getIdentitySkillAddition(eSkillType.StaffRecruitCost.getValue(), buildingInfo.getOccupation());
			BigDecimal cost = buildingInfo.getAddStaffCost().multiply(buildingStaffMap.get(count).getConsume()).divide(BigDecimal.valueOf(1000000));
			cost = cost.multiply(BigDecimal.valueOf(skillAddition / 1000 + 1)).setScale(0, BigDecimal.ROUND_UP);
			return cost;
		}
		return null;
	}

	public static int getBuildingMaxLevel(GamePlayer player, int occupation){
		int skillAddition = player.getModule(BeautyModule.class).getIdentitySkillAddition(eSkillType.BuildingLevel.getValue(), occupation);  //美名
		skillAddition += player.getModule(PatronsModule.class).getTalentSkillAddition(eSkillType.BuildingLevel.getValue(), occupation);   //天赋
		return GameConfig.BUILDING_MAX_LEVEL + skillAddition;
	}

	/**
	 * 根据建筑Id 获取建筑在列表中的位置
	 */
	public static int getBuildingIndex(int buildingId) {
		BuildingInfo buildingInfo = buildingInfoMap.get(buildingId);
		if(null != buildingInfo){
			return buildingInfo.getPosition();
		}
		return -1;
	}

	public static BuildingUpgrade getBuildingUpgrade(int buildingId, int level) {
		if(buildingUpgradeMap.containsKey(buildingId)){
			return buildingUpgradeMap.get(buildingId).get(level);
		}
		return null;
	}

	public static BigDecimal getBuildingEarnSpeed(GamePlayer player, UserBuilding userBuilding){
		if(null == userBuilding){
			return BigDecimal.ZERO;
		}
		BigInteger old = userBuilding.getBuildingEarnSpeed();
		BigDecimal earnSpeed;
		//单伙计赚速
		BigDecimal h = BigDecimal.ZERO;
		BuildingInfo buildingInfo = BuildingMgr.getBuildingInfo(userBuilding.getBuildingId());
		if(null != buildingInfo) {
			h = buildingInfo.getStaffEarnSpeed();
		}
		//庄园对伙计赚速加成
		h = h.add(getManorStaffEarnAddValue(player, userBuilding).divide(BigDecimal.valueOf(1000), 2, BigDecimal.ROUND_UP));
		//药铺对伙计赚钱加成
		h = h.add(getDrugStoreEarnAddValue(player, userBuilding).divide(BigDecimal.valueOf(1000), 2, BigDecimal.ROUND_UP));
		//藏宝系统对伙计赚钱固定值
		h = h.add(getCurioStaffEarnAddValue(player, userBuilding).divide(BigDecimal.valueOf(1000), 3, BigDecimal.ROUND_UP));
		//伙计数量
		BigDecimal n = BigDecimal.valueOf(userBuilding.getStaffCount());
		//伙计数量固定值加成
		long staffCountAdd = CurioMgr.getSkillAdditionBySkillType(eSkillType.SpecialBuildingStaffRecruitNumAddSkill.getValue(), player, userBuilding.getBuildingId());
		userBuilding.setAddStaffCount((int)staffCountAdd);
		n = n.add(BigDecimal.valueOf(staffCountAdd));
		//第一次计算
		BigDecimal value1 = h.multiply(n);

		//门客赚速
		BigDecimal z = new BigDecimal(player.getModule(PatronsModule.class).getTotalPatronsAbility());

		//第二次计算
		BigDecimal value2 = z.divide(BigDecimal.valueOf(ConfigMgr.getPatronsAbilityParam5()));
		value2 = value2.add(value1);

		BigDecimal addition = getBuildAddition(player, userBuilding, buildingInfo);
		//最后计算
		earnSpeed = value2.multiply(addition).setScale(0, BigDecimal.ROUND_UP);

		if(Config.isDebug()){
			//getLogger().info("================店铺{}赚钱变更：{}->{}", userBuilding.getBuildingId(), old, earnSpeed);
		}
		return earnSpeed;
	}

	private static BigDecimal getCurioStaffEarnAddValue(GamePlayer player, UserBuilding userBuilding) {
		BigDecimal addValue = BigDecimal.ZERO;
		return addValue.add(BigDecimal.valueOf(CurioMgr.getSkillAdditionBySkillType(eSkillType.CurioBuildingStaffSkill.getValue(), player, userBuilding.getBuildingId())));
	}

	public static BigDecimal getBuildAddition(GamePlayer player, UserBuilding userBuilding, BuildingInfo buildingInfo) {
		//初步加成
		BigDecimal addition = BigDecimal.ONE;
		//升级店铺的加成
		BuildingUpgrade buildingUpgrade = BuildingMgr.getBuildingUpgrade(userBuilding.getBuildingId(), userBuilding.getLevel());
		if(null != buildingUpgrade){
			addition = BigDecimal.valueOf((double) buildingUpgrade.getEarnSpeedAddition() / 1000).setScale(4, BigDecimal.ROUND_UP);
		}

		//藏品加成
//			int collectionAddition = player.getModule(CollectionModule.class).getTotalCollectionAddition();
//			if(collectionAddition > 0) {
//				addition = addition.add(BigDecimal.valueOf((double)collectionAddition / 1000).setScale(4, BigDecimal.ROUND_UP));
//			}
		//藏宝系统-特定商铺加成
		addition = addition.add(BigDecimal.valueOf(((double)CurioMgr.getSkillAdditionBySkillType(eSkillType.CurioOccupationBuildingEarnSkill.getValue(), player, buildingInfo.getOccupation())) / 1000).setScale(4, BigDecimal.ROUND_UP));
		addition = addition.add(BigDecimal.valueOf(((double)CurioMgr.getSkillAdditionBySkillType(eSkillType.CurioBuildingEarnSkill.getValue(), player, buildingInfo.getId())) / 1000).setScale(4, BigDecimal.ROUND_UP));

		//美女对店铺加成
		addition = addition.add(BigDecimal.valueOf(getBeautyEarnSpeedAddition(player, userBuilding) / 1000).setScale(4, BigDecimal.ROUND_UP));

		//派遣门客的加成
		addition = addition.add(BigDecimal.valueOf(getDispatchPatronsAddition(player, userBuilding) / 1000).setScale(4, BigDecimal.ROUND_UP));

		//乔迁风云府邸赚速加成
		addition = addition.add(BigDecimal.valueOf(((double)player.getModule(EstateWarModule.class).getEarnSpeedAddition()) / 1000).setScale(4, BigDecimal.ROUND_UP));

		//钱庄赚速加成
		addition = addition.add(BigDecimal.valueOf(((double)player.getModule(HouseModule.class).getEarnSpeedAddition()) / 1000).setScale(4, BigDecimal.ROUND_UP));

		//商会议事厅赚速加成
		addition = addition.add(BigDecimal.valueOf(getUnionChamberDispatchAddition(player, userBuilding) / 1000).setScale(4, BigDecimal.ROUND_UP));

		//商会旗帜赚速加成
		addition = addition.add(BigDecimal.valueOf(getUnionFlagBuildingAddition(player, userBuilding, buildingInfo) / 1000).setScale(4, BigDecimal.ROUND_UP));

		//医馆赚速加成
		addition = addition.add(BigDecimal.valueOf(getClinicEarnSpeedAddition(player, userBuilding) / 1000).setScale(4, BigDecimal.ROUND_UP));

		//药铺等级加成
		addition = addition.add(BigDecimal.valueOf(getDrugStoreEarnSpeedAddition(player, userBuilding) / 1000).setScale(4, BigDecimal.ROUND_UP));

		//药铺处方加成
		//addition = addition.add(BigDecimal.valueOf(getDrugStoreChuFangEarnSpeedAddition(player, userBuilding) / 1000).setScale(4, BigDecimal.ROUND_UP));

		//庄园科技加成
		addition = addition.add(BigDecimal.valueOf(getManorBuildingEarnAddRatio(player, userBuilding) / 1000).setScale(4, BigDecimal.ROUND_UP));

		//鱼塘徽章加成
		addition = addition.add(BigDecimal.valueOf(getFishPondBadgeAddRatio(player, userBuilding) / 1000).setScale(4, BigDecimal.ROUND_UP));

		//厢房徽章加成
		addition = addition.add(BigDecimal.valueOf(getWingRoomBadgeAddRio(player, userBuilding) / 1000).setScale(4, BigDecimal.ROUND_UP));
		// 府邸皮肤加成
		addition = addition.add(BigDecimal.valueOf(getHouseSkinAddRio(player, userBuilding) / 1000).setScale(4, RoundingMode.UP));
		// 钱庄皮肤加成
		addition = addition.add(BigDecimal.valueOf(getBankSkinAddRio(player, userBuilding) / 1000).setScale(4, RoundingMode.UP));

		//酒坊加成
		BigDecimal wineryAddition = BigDecimal.valueOf(getWineryEarnSpeedAddition(player, userBuilding) / 1000).setScale(4, RoundingMode.UP);
		addition = addition.add(wineryAddition);

		addition = addition.add(BigDecimal.valueOf(getWineryBadgeAddRio(player, userBuilding) / 1000).setScale(4, RoundingMode.UP));

		// 蛐蛐加成
		addition = addition.add(BigDecimal.valueOf(getCricketBadgeAddRio(player, userBuilding) / 1000).setScale(4, BigDecimal.ROUND_UP));

		// 九龙城寨加成
		addition = addition.add(BigDecimal.valueOf(getKowloonAddRio(player, userBuilding) / 1000).setScale(4, BigDecimal.ROUND_UP));

		//妙音坊加成
		addition = addition.add(BigDecimal.valueOf(getMusicRoomAddRio(player, userBuilding) / 1000).setScale(4, BigDecimal.ROUND_UP));

		//藏宝
		addition = addition.add(BigDecimal.valueOf(getCurioBadgeAddRio(player, userBuilding) / 1000).setScale(4, BigDecimal.ROUND_UP));

		// 寒冬特色服加成
		addition = addition.add(BigDecimal.valueOf(getIceServerAddRio(player, userBuilding) / 1000).setScale(4, BigDecimal.ROUND_UP));

		return addition;
	}

	private static double getHouseSkinAddRio(GamePlayer player, UserBuilding userBuilding) {
		double addition = 0;
		BuildingInfo buildingInfo = BuildingMgr.getBuildingInfo(userBuilding.getBuildingId());
		if (buildingInfo != null) {
			List<Integer> skinIdList = player.getModule(SkinModule.class).getSkinIdList(eSkinType.EstateSkin);
			if (skinIdList != null) {
				for (Integer skinId : skinIdList) {
					UserSkin userSkin = player.getModule(SkinModule.class).getUserSkin(skinId);
					int level = userSkin.getLevel();
					SkinInfo skinInfo = SkinMgr.getSkinInfo(skinId);
					if (skinInfo != null) {
						List<Integer> effectList = skinInfo.getSkinEffect();
						if (effectList != null) {
							for (Integer skillId : effectList) {
								SkillInfo skillInfo = SkillMgr.getSkillInfo(skillId);
								if (skillInfo != null) {
									if (skillInfo.getType() == eSkillType.ManorBuildingTypeEarnAddRatio.getValue()) {
										if (skillInfo.getParamList().get(2) == 0 || skillInfo.getParamList().get(2) == buildingInfo.getOccupation()) {
											addition += SkillMgr.getSkillAddition(skillInfo, level);
										}
									}
								}
							}
						}

					}
				}
			}
		}
		return addition;
	}

	private static double getBankSkinAddRio(GamePlayer player, UserBuilding userBuilding) {
		double addition = 0;
		BuildingInfo buildingInfo = BuildingMgr.getBuildingInfo(userBuilding.getBuildingId());
		if (buildingInfo != null) {
			List<Integer> skinIdList = player.getModule(SkinModule.class).getSkinIdList(eSkinType.BankSkin);
			if (skinIdList != null) {
				for (Integer skinId : skinIdList) {
					UserSkin userSkin = player.getModule(SkinModule.class).getUserSkin(skinId);
					int level = userSkin.getLevel();
					SkinInfo skinInfo = SkinMgr.getSkinInfo(skinId);
					if (skinInfo != null) {
						List<Integer> effectList = skinInfo.getSkinEffect();
						if (effectList != null) {
							for (Integer skillId : effectList) {
								SkillInfo skillInfo = SkillMgr.getSkillInfo(skillId);
								if (skillInfo != null) {
									if (skillInfo.getType() == eSkillType.BankSkillShopAdd.getValue()) {
										if (skillInfo.getParamList().get(2) == 0 || skillInfo.getParamList().get(2) == buildingInfo.getOccupation()) {
											addition += SkillMgr.getSkillAddition(skillInfo, level);
										}
									}
								}
							}
						}
					}
				}
			}
		}
		return addition;
	}

	/**
	 * 药铺处方对赚速的加成
	 * @param player
	 * @param userBuilding
	 * @return
	 */
	private static double getDrugStoreChuFangEarnSpeedAddition(GamePlayer player, UserBuilding userBuilding){
		double addition = 0;
		BuildingInfo buildingInfo = BuildingMgr.getBuildingInfo(userBuilding.getBuildingId());
		DrugStoreModule storeModule = player.getModule(DrugStoreModule.class);
		UserDrugStoreData drugStoreData = storeModule.getUserDrugStoreData();
		if(drugStoreData != null){
			for (Map.Entry<Integer, UserDrugChuFangData> dataEntry : storeModule.getChuFangDataMap().entrySet()) {
				UserDrugChuFangData chuFangData = dataEntry.getValue();
				DrugStoreDrugUpgradeInfo upgradeInfo = DrugStoreConfigMgr.getDrugStoreDrugUpgradeInfo(chuFangData.getChuFang(), chuFangData.getLv());
				if(upgradeInfo != null){
					for (int skillId : upgradeInfo.getSkillList()) {
						SkillInfo skillInfo = SkillMgr.getSkillInfo(skillId);
						if(skillInfo != null){
							if(skillInfo.getParamList().get(2) != buildingInfo.getOccupation()){
								continue;
							}
							addition += SkillMgr.getSkillAddition(skillInfo, chuFangData.getLv());
						}
					}
				}

			}
		}
		return addition;
	}

	/**
	 * 药铺等级对赚速的加成
	 * @param player
	 * @param userBuilding
	 * @return
	 */
	private static double getDrugStoreEarnSpeedAddition(GamePlayer player, UserBuilding userBuilding){
		double addition = 0;
		UserDrugStoreData drugStoreData = player.getModule(DrugStoreModule.class).getUserDrugStoreData();
		if(drugStoreData != null){
			DrugStoreBadgeInfo badgeInfo = DrugStoreConfigMgr.getDrugStoreBadgeInfo(drugStoreData.getDrugStoreLv());
			if(badgeInfo != null){
				for (int skillId : badgeInfo.getSkillsList()) {
					SkillInfo skillInfo = SkillMgr.getSkillInfo(skillId);
					if(skillInfo != null){
						addition += SkillMgr.getSkillAddition(skillInfo, drugStoreData.getDrugStoreLv());
					}
				}
			}
		}
		return addition;
	}

	/**
	 * 医馆病症对赚速的加成
	 * @param player
	 * @param userBuilding
	 * @return
	 */
	private static double getClinicEarnSpeedAddition(GamePlayer player, UserBuilding userBuilding) {
		double addition = 0;
		BuildingInfo buildingInfo = BuildingMgr.getBuildingInfo(userBuilding.getBuildingId());
		UserClinicData userClinicData = player.getModule(ClinicModule.class).getUserClinicData();
		if (userClinicData != null) {
			Map<Integer, DiseaseData> diseaseDataMap = userClinicData.getDiseaseDataMap();
			if (diseaseDataMap != null) {
				for (DiseaseData data : diseaseDataMap.values()) {
					DiseaseInfo diseaseInfo = ClinicMgr.getDiseaseInfo(data.getId());
					if (diseaseInfo != null) {
						SkillInfo skillInfo = SkillMgr.getSkillInfo(diseaseInfo.getSkill());
						if (skillInfo != null && (skillInfo.getParamList().get(2) == 0 || skillInfo.getParamList().get(2) == buildingInfo.getOccupation())) {
							addition += SkillMgr.getSkillAddition(skillInfo, data.getLevel());
						}
					}
				}
			}
		}
		return addition;
	}

	/**
	 * 美女技能对店铺加成
	 */
	public static double getBeautyEarnSpeedAddition(GamePlayer player, UserBuilding userBuilding){
		double addition = 0;
		BuildingInfo buildingInfo = BuildingMgr.getBuildingInfo(userBuilding.getBuildingId());
		Map<Integer, UserBeauty> beautyMap = player.getModule(BeautyModule.class).getBeautyMap();
		if(null == beautyMap){
			return 0;
		}
		for(UserBeauty beauty : beautyMap.values()){
			for(UserBeautySkill userBeautySkill : beauty.getSkillMap().values()){
				BeautySkillInfo skillInfo = BeautyMgr.getBeautySkillInfo(userBeautySkill.getSkillPos());
				if (skillInfo == null) {
					getLogger().error("BeautySkillInfo is null! ,beautyId:{},skillPos:{}", beauty.getBeautyId(), userBeautySkill.getSkillPos());
					continue;
				}
				if (skillInfo.isScholarAddition()) {
					if (buildingInfo.getOccupation() == eOccupationType.Scholar.getValue()) {
						addition = addition + userBeautySkill.getSkillValue() * 10;
					}
				}
				if (skillInfo.isFarmerAddition()) {
					if (buildingInfo.getOccupation() == eOccupationType.Farmer.getValue()) {
						addition = addition + userBeautySkill.getSkillValue() * 10;
					}
				}
				if (skillInfo.isCraftsmanAddition()) {
					if (buildingInfo.getOccupation() == eOccupationType.Craftsman.getValue()) {
						addition = addition + userBeautySkill.getSkillValue() * 10;
					}
				}
				if (skillInfo.isBusinessmanAddition()) {
					if (buildingInfo.getOccupation() == eOccupationType.Businessman.getValue()) {
						addition = addition + userBeautySkill.getSkillValue() * 10;
					}
				}
				if (skillInfo.isKnightAddition()) {
					if (buildingInfo.getOccupation() == eOccupationType.Knight.getValue()) {
						addition = addition + userBeautySkill.getSkillValue() * 10;
					}
				}
			}
		}
		return addition;
	}

	/**
	 * 派遣门客对店铺加成
	 */
	public static double getDispatchPatronsAddition(GamePlayer player, UserBuilding userBuilding){
		double addition = 0;

		// 武镖师天赋：每个门客加一次
		int talentSkillAddition = player.getModule(PatronsModule.class).getTalentSkillAddition(eSkillType.PatronsDispatchBuildingAddition.getValue(), 0);
		addition += (talentSkillAddition * userBuilding.getPatronsIdList().size());

		for(int patronsId : userBuilding.getPatronsIdList()){
			UserPatrons userPatrons = player.getModule(PatronsModule.class).getUserPatrons(patronsId);
			for(UserPatronsSkill patronsSkill : userPatrons.getSkillList()){
				SkillInfo skillInfo = SkillMgr.getSkillInfo(patronsSkill.getSkillId());
				if (skillInfo == null) {
					continue;
				}
				if (eSkillType.DispatchEarn.getValue() == skillInfo.getType()) {
					addition += SkillMgr.getSkillAddition(skillInfo, patronsSkill.getSkillLv());
				}
			}
		}
		return addition;
	}

	public static double getUnionFlagBuildingAddition(GamePlayer player, UserBuilding userBuilding, BuildingInfo buildingInfo){
		double addition = 0;
		String unionUid = player.getUserInfo().getUnionUid();
		if(StringUtils.isNullOrEmpty(unionUid)){
			return addition;
		}
		CrossUnionInfo unionInfo = CrossUnionMgr.getUnionInfo(unionUid);
		if(unionInfo == null){
			return addition;
		}

		for (int flagId : unionInfo.getAllFlagList()) {
			GoodsInfo goodsInfo = GoodsMgr.getGoodsById(flagId);
			if(goodsInfo == null){
				continue;
			}
			List<String> extendParamList = StringUtils.stringToStringList(goodsInfo.getExtendParam(), "\\|");
			int skillId = Integer.valueOf(extendParamList.get(0));
			SkillInfo skillInfo = SkillMgr.getSkillInfo(skillId);
			if (skillInfo == null) {
				continue;
			}
			if(buildingInfo.getOccupation() != skillInfo.getParamList().get(2)){
				continue;
			}
			addition += SkillMgr.getSkillAddition(skillInfo, 1);
			//getLogger().debug("userBuilding addition flagId {} - {} - {}", userBuilding.getBuildingId(), addition, flagId);
		}
		return addition;
	}

	public static double getUnionChamberDispatchAddition(GamePlayer player, UserBuilding userBuilding){
		double addition = 0;
		String unionUid = player.getUserInfo().getUnionUid();
		if(StringUtils.isNullOrEmpty(unionUid)){
			return addition;
		}
		Map<Long, CrossUnionMember> memberMap = CrossUnionMgr.getUnionMemberMap(unionUid);
		if(null == memberMap){
			return addition;
		}
		BuildingInfo buildingInfo = getBuildingInfo(userBuilding.getBuildingId());
		for(CrossUnionMember unionMember : memberMap.values()) {
//			if(null != unionMember.getChamberPatron()) {
//				PatronsInfo patronsInfo = PatronsMgr.getPatronsInfo(unionMember.getChamberPatron().getPatronsId());
//				if (patronsInfo.getOccupation() != buildingInfo.getOccupation()) {
//					continue;
//				}
//				for (UserPatronsSkill patronsSkill : unionMember.getChamberPatron().getSkillList()) {
//					SkillInfo skillInfo = SkillMgr.getSkillInfo(patronsSkill.getSkillId());
//					if (eSkillType.DispatchEarn.getValue() == skillInfo.getType()) {
//						addition += SkillMgr.getSkillAddition(skillInfo, patronsSkill.getSkillLv());
//					}
//				}
//			}
			if(null != unionMember.getChamberPatrons() && unionMember.getChamberPatronsId() > 0){
				PatronsInfo patronsInfo = PatronsMgr.getPatronsInfo(unionMember.getChamberPatrons().getPatronsId());
				if (patronsInfo.getOccupation() != buildingInfo.getOccupation()) {
					continue;
				}
				for (CrossPatronsSkill patronsSkill : unionMember.getChamberPatrons().getSkillList()) {
					SkillInfo skillInfo = SkillMgr.getSkillInfo(patronsSkill.getId());
					if (eSkillType.DispatchEarn.getValue() == skillInfo.getType()) {
						addition += SkillMgr.getSkillAddition(skillInfo, patronsSkill.getLv());
					}
				}
			}
		}
		return addition;
	}

	/**
	 * 药铺单个伙计赚速加成固定值
	 * @param player
	 * @param userBuilding
	 * @return
	 */
	public static BigDecimal getDrugStoreEarnAddValue(GamePlayer player, UserBuilding userBuilding) {
		BigDecimal addValue = BigDecimal.ZERO;
		return addValue.add(BigDecimal.valueOf(player.getModule(DrugStoreModule.class).getTechnologyAdd(userBuilding)));
	}

	/**
	 * 庄园单个伙计赚速加成固定值
	 * @param player
	 * @param userBuilding
	 * @return
	 */
	public static BigDecimal getManorStaffEarnAddValue(GamePlayer player, UserBuilding userBuilding) {
		BigDecimal addValue = BigDecimal.ZERO;
		ManorTechnologyModel technologyModel = player.getModule(ManorModule.class).getTechnologyModel();
		if (technologyModel == null) {
			return addValue;
		}
		Map<Integer, ManorTechnologyData> technologyDataMap = technologyModel.getTechnologyDataMap();
		if (technologyDataMap != null) {
			addValue = addValue.add(BigDecimal.valueOf(ManorMgr.getManorAddValue(userBuilding.getBuildingId(), technologyDataMap, eSkillType.ManorBuildingStaffEarnAddition.getValue()))) ;
		}
		return addValue;
	}

	/**
	 * 庄园商铺加成千分比
	 * @param player
	 * @param userBuilding
	 * @return
	 */
	private static double getManorBuildingEarnAddRatio(GamePlayer player, UserBuilding userBuilding) {
		double addRatio = 0;
		ManorTechnologyModel technologyModel = player.getModule(ManorModule.class).getTechnologyModel();
		if (technologyModel != null) {
			Map<Integer, ManorTechnologyData> technologyDataMap = technologyModel.getTechnologyDataMap();
			if (technologyDataMap != null) {
				addRatio += ManorMgr.getManorAddValue(userBuilding.getBuildingId(), technologyDataMap, eSkillType.ManorBuildingEarnAddRatio.getValue());
			}
		}

		ManorHarvestModel harvestModel = player.getModule(ManorModule.class).getHarvestModel();
		if (harvestModel != null) {
			for (ManorHarvestData harvestData : harvestModel.getHarvestDataMap().values()) {
				ManorConfig manorConfig = ManorMgr.getManorConfigMap().get(harvestData.getOutPutId());
				if (manorConfig != null) {
					int skillId = Integer.parseInt(manorConfig.getSkill().split("\\|")[1]);
					SkillInfo skillInfo = SkillMgr.getSkillInfo(skillId);
					if (skillInfo != null) {
						BuildingInfo buildingInfo = BuildingMgr.getBuildingInfo(userBuilding.getBuildingId());
						if (buildingInfo != null) {
							if (skillInfo.getParamList().get(2) == 0 || skillInfo.getParamList().get(2) == buildingInfo.getOccupation()) {
								addRatio += SkillMgr.getSkillAddition(skillInfo, harvestData.getSpecialSkillLv());
							}
						}
					}
				}
			}
		}
		return addRatio;
	}

	private static double getFishPondBadgeAddRatio(GamePlayer player, UserBuilding userBuilding) {
		double addition = 0;
		BuildingInfo buildingInfo = BuildingMgr.getBuildingInfo(userBuilding.getBuildingId());
		if (buildingInfo != null) {
			addition += FishPondMgr.getBuildingSpeedAddition(player, eSkillType.ManorBuildingTypeEarnAddRatio.getValue(), buildingInfo.getOccupation());
		}
		return addition;
	}


	private static double getWingRoomBadgeAddRio(GamePlayer player, UserBuilding userBuilding) {
		double addition = 0;
		BuildingInfo buildingInfo = BuildingMgr.getBuildingInfo(userBuilding.getBuildingId());
		if (buildingInfo != null) {
			UserWingRoomData wingRoomData = player.getModule(WingRoomModule.class).getWingRoomData();
			if (wingRoomData != null) {
				int lv = wingRoomData.getLv();
				WingRoomLvConfig wingRoomLvConfig = WingRoomConfigMgr.getWingRoomLvConfig(lv);
				if (wingRoomLvConfig != null) {
					for (Integer skillId : wingRoomLvConfig.getSkillList()) {
						SkillInfo skillInfo = SkillMgr.getSkillInfo(skillId);
						if (skillInfo != null) {
							if (skillInfo.getType() == eSkillType.ManorBuildingTypeEarnAddRatio.getValue() && (skillInfo.getParamList().get(2) == 0 || skillInfo.getParamList().get(2) == buildingInfo.getOccupation())) {
								addition += SkillMgr.getSkillAddition(skillInfo, lv);
							}
						}
					}
				}
			}
		}
		return addition;
	}
	private static double getWineryEarnSpeedAddition(GamePlayer player, UserBuilding userBuilding) {
		double addition = 0;
		BuildingInfo buildingInfo = getBuildingInfo(userBuilding.getBuildingId());
		if (buildingInfo == null) {
			return addition;
		}
		Map<Integer, UserWineryData> userWineryDataMap = player.getModule(WineryModule.class).getUserWineryDataMap();
		for (UserWineryData userWineryData : userWineryDataMap.values()) {
			WineryConfig wineryConfig = WineryConfigMgr.getWineryConfig(userWineryData.getWineryId());
			if (wineryConfig == null) {
				continue;
			}
			List<Integer> skillList = wineryConfig.getSkillList();
			for (Integer skillId : skillList) {
				SkillInfo skillInfo = SkillMgr.getSkillInfo(skillId);
				if (skillInfo == null) {
					continue;
				}
				if (skillInfo.getType() != eSkillType.ClinicDiseaseEarnSpeedAddition.getValue()) {
					continue;
				}

				if (skillInfo.getParamList().get(2) != buildingInfo.getOccupation()) {
					continue;
				}

				Integer base = skillInfo.getParamList().get(1);
				Integer upgrade = skillInfo.getUpgradeParamList().get(1);
				upgrade = base + (userWineryData.getLevel() -1)*upgrade;
				addition += upgrade;
			}
		}
		return addition;

	}
	private static double getWineryBadgeAddRio(GamePlayer player, UserBuilding userBuilding) {
		double addition = 0;
		BuildingInfo buildingInfo = BuildingMgr.getBuildingInfo(userBuilding.getBuildingId());
		if (buildingInfo == null) {
			return addition;
		}

		UserWineryInfoData userWineryInfoData = player.getModule(WineryModule.class).getUserWineryInfoData();
		if (userWineryInfoData == null) {
			return addition;
		}
		int lv = userWineryInfoData.getBadgeLevel();
		BadgeConfig wineryBadgeConfig = BadgeConfigMgr.getWineryBadgeConfig(lv);
		if (wineryBadgeConfig == null) {
			return addition;
		}

		for (Integer skillId : wineryBadgeConfig.getSkillIdList()) {
			SkillInfo skillInfo = SkillMgr.getSkillInfo(skillId);
			if (skillInfo == null) {
				continue;
			}
			if (skillInfo.getType() == eSkillType.ManorBuildingTypeEarnAddRatio.getValue() && (skillInfo.getParamList().get(2) == 0 || skillInfo.getParamList().get(2) == buildingInfo.getOccupation())) {
				addition += SkillMgr.getSkillAddition(skillInfo, lv);
			}
		}
		return addition;
	}


	private static double getCricketBadgeAddRio(GamePlayer player, UserBuilding userBuilding) {
		double addition = 0;
		if (!SystemOpenMgr.systemOpen(player, eSystemId.BadgeShow.getValue()) || !SystemOpenMgr.systemOpen(player, eSystemId.Cricket.getValue())) {
			return addition;
		}
		BuildingInfo buildingInfo = BuildingMgr.getBuildingInfo(userBuilding.getBuildingId());
		if (buildingInfo != null) {
			UserCricketData userCricketData = player.getModule(CricketModule.class).getUserCricketData();
			if (userCricketData != null) {
				int lv = userCricketData.getBadgeLevel();
				BadgeConfig cricketConfig = BadgeConfigMgr.getBadgeConfigByLevel(eBadgeType.Cricket.getValue(), lv);
				if (cricketConfig != null) {
					for (Integer skillId : cricketConfig.getSkillIdList()) {
						SkillInfo skillInfo = SkillMgr.getSkillInfo(skillId);
						if (skillInfo != null) {
							if (skillInfo.getType() == eSkillType.ManorBuildingTypeEarnAddRatio.getValue() && (skillInfo.getParamList().get(2) == 0 || skillInfo.getParamList().get(2) == buildingInfo.getOccupation())) {
								addition += SkillMgr.getSkillAddition(skillInfo, lv);
							}
						}
					}
				}
			}
		}
		return addition;
	}

	/**
	 * 寒冬特色服加成
	 * @param player
	 * @param userBuilding
	 * @return
	 */
	private static double getIceServerAddRio(GamePlayer player, UserBuilding userBuilding) {
		double addition = 0;
		ServerInfo serverInfo = ServerListMgr.getServerInfo(GameServer.getInstance().getServerId());
		if (serverInfo.getSpecialServer() != eSpecialServerType.IceServer.getValue() && !SystemOpenMgr.systemOpen(player, eSystemId.IceServer.getValue())) {
			return addition;
		}
		IceServerModule iceServerModule = player.getModule(IceServerModule.class);
		if (iceServerModule == null || iceServerModule.getUserData() == null) {
			return addition;
		}
		if (iceServerModule.getUserData().getTaskFinishTime() == 0
				|| System.currentTimeMillis() > (iceServerModule.getUserData().getTaskFinishTime() + GameConfig.ICE_SERVER_BUILD_SPEED_TIME * DateHelper.SECOND_MILLIONS)
				|| System.currentTimeMillis() < iceServerModule.getUserData().getTaskFinishTime()) {
			return addition;
		}
		BuildingInfo buildingInfo = BuildingMgr.getBuildingInfo(userBuilding.getBuildingId());
		if (buildingInfo != null) {
			SkillInfo skillInfo = SkillMgr.getSkillInfo(GameConfig.ICE_SERVER_REWARD_SKILL);
			if (skillInfo != null) {
				if (skillInfo.getType() == eSkillType.ManorBuildingTypeEarnAddRatio.getValue()) {
					addition += SkillMgr.getSkillAddition(skillInfo, 1);
				}
			}
		}
		return addition;
	}

	private static double getCurioBadgeAddRio(GamePlayer player, UserBuilding userBuilding) {
		double addition = 0;
		if (!SystemOpenMgr.systemOpen(player, eSystemId.Curio.getValue())) {
			return addition;
		}
		BuildingInfo buildingInfo = BuildingMgr.getBuildingInfo(userBuilding.getBuildingId());
		if (buildingInfo != null) {
			UserCurioData userCurioData = player.getModule(CurioModule.class).getUserCurioData();
			if (userCurioData != null) {
				int lv = userCurioData.getBadgeLv();
				CurioBadgeInfo badgeInfo = CurioConfigMgr.getConfig().getBadgeInfo(lv);
				if (badgeInfo != null) {
					for (Integer skillId : badgeInfo.getSkillsList()) {
						SkillInfo skillInfo = SkillMgr.getSkillInfo(skillId);
						if (skillInfo != null) {
							if (skillInfo.getType() == eSkillType.ManorBuildingTypeEarnAddRatio.getValue() && (skillInfo.getParamList().get(2) == 0 || skillInfo.getParamList().get(2) == buildingInfo.getOccupation())) {
								addition += SkillMgr.getSkillAddition(skillInfo, lv);
							}
						}
					}
				}
			}
		}
		return addition;
	}

	private static double getKowloonAddRio(GamePlayer player, UserBuilding userBuilding) {
		double addition = 0;
		ServerInfo serverInfo = ServerListMgr.getServerInfo(GameServer.getInstance().getServerId());
		if (serverInfo.getSpecialServer() != eSpecialServerType.Kowloon.getValue() && !SystemOpenMgr.systemOpen(player, eSystemId.Kowloon.getValue())) {
			return addition;
		}
		KowloonConfig config = KowloonMgr.getConfig();
		if (config == null) {
			return addition;
		}
		BuildingInfo buildingInfo = BuildingMgr.getBuildingInfo(userBuilding.getBuildingId());
		if (buildingInfo != null) {
			Map<Integer, KowloonBuildingData> buildingDataMap = player.getModule(KowloonModule.class).getBuildingDataMap();
			for (KowloonBuildingData buildingData : buildingDataMap.values()) {
				int buildingId = buildingData.getBuildingId();
				int lv = buildingData.getLevel();
				KowloonBuildingConfig buildingConfig = config.getKowloonBuildingConfig(buildingId, lv);
				if (buildingConfig == null) {
					continue;
				}
				for (String skillParam : buildingConfig.getSkillsList()) {
					String[] param = skillParam.split(";");
					SkillInfo skillInfo = SkillMgr.getSkillInfo(Integer.parseInt(param[0]));
					if (skillInfo != null) {
						if (skillInfo.getType() == eSkillType.ManorBuildingTypeEarnAddRatio.getValue() && (skillInfo.getParamList().get(2) == 0 || skillInfo.getParamList().get(2) == buildingInfo.getOccupation())) {
							addition += SkillMgr.getSkillAddition(skillInfo, Integer.parseInt(param[1]));
						}
					}
				}
			}
		}
		return addition;
	}

	public static double getMusicRoomAddRio(GamePlayer player, UserBuilding userBuilding) {
		double addition = 0;
		BuildingInfo buildingInfo = BuildingMgr.getBuildingInfo(userBuilding.getBuildingId());
		if (buildingInfo == null) {
			return addition;
		}
		if (!SystemOpenMgr.systemOpen(player, eSystemId.MusicRoom.getValue())) {
			return addition;
		}

		int badgeLevel = (int)player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.MusicRoomBadgeLevel);
		BadgeConfig badgeConfig = BadgeConfigMgr.getBadgeConfigByLevel(eBadgeType.MusicRoom.getValue(), badgeLevel);
		if (badgeConfig == null) {
			return addition;
		}

		for (Integer skillId : badgeConfig.getSkillIdList()) {
			SkillInfo skillInfo = SkillMgr.getSkillInfo(skillId);
			if (skillInfo != null) {
				if (skillInfo.getType() == eSkillType.ManorBuildingTypeEarnAddRatio.getValue() && (skillInfo.getParamList().get(2) == 0 || skillInfo.getParamList().get(2) == buildingInfo.getOccupation())) {
					addition += SkillMgr.getSkillAddition(skillInfo, badgeLevel);
				}
			}
		}

		return addition;
	}


}
